module derived
  use param

  ! Point defect
  type PointType
     integer :: len
     character(len=max_n_char) :: ch
     integer,pointer,dimension(:) :: uppercase
     integer,pointer,dimension(:) :: lowercase
  end type PointType

  ! Save the set of objects
  type save_cascade_set
     integer :: nlist
     integer,pointer,dimension(:) :: clist
  end type save_cascade_set

  ! Object
  type Object
     integer :: obj_type
     real(dbl) :: pos(3)
     real(dbl) :: vec(3)
     integer :: dir
  end type Object

  ! A sets of objects
  type ObjectSet
     integer :: n_obj
     real(dbl) :: pka_e
     type(Object),pointer,dimension(:) :: obj
  end type ObjectSet

  ! External event
  type ExternalEvent
     integer :: event_type
     real(dbl) :: flux
     real(dbl) :: dose
     integer :: rand
     real(dbl) :: rate_const
     integer :: n_occur
     integer :: max_n_occur
     ! Only for event type 1 and 2 (neutorn and ion)
     character(len=len_fn) :: filename
     character(len=len_fn) :: dpa_filename
     character(len=len_fn) :: cas_filename
     ! cdf for subcascade densities
     integer :: n_cas
     real(dbl),pointer,dimension(:) :: cgrid,cprob
     integer,pointer,dimension(:) :: count_cascade
     type(save_cascade_set),pointer,dimension(:) :: cascade_list
     real(dbl) :: clength,partial_sdpa,sub_e
     ! cdf only for dpa calculation
     integer :: n_dpa
     real(dbl),pointer,dimension(:) :: dgrid,dprob
     real(dbl) :: dlength,partial_dpa,dpa_e
     ! Save a sets of object groups
     integer :: n_objset
     type(ObjectSet),pointer,dimension(:) :: objset
     ! Calculation for dpa
     real(dbl) :: dise
     real(dbl) :: dpa,sdpa
     ! Count how many times dose the event occur?
     integer,pointer,dimension(:) :: count_dpa
     ! electron irradiation
     real(dbl) :: dist(2)
     integer :: n_type
     character(len=len_wordbuf),pointer,dimension(:) :: source_name
     integer,pointer,dimension(:) :: source_type
  end type ExternalEvent

  ! Group of defect
  type GroupType
     integer :: index
     integer :: n_point
     integer :: group_type
     integer,pointer,dimension(:) :: point_type
     integer,pointer,dimension(:) :: min_size
     integer,pointer,dimension(:) :: max_size
     integer :: total_size
     integer :: single_type
  end type GroupType

  ! Count spatial distribution
  type CountSpatialDistribution
     integer,pointer,dimension(:) :: nx
     integer,pointer,dimension(:) :: ny
     integer,pointer,dimension(:) :: nz
     integer :: group_type
     integer :: point_type
  end type CountSpatialDistribution

  ! Filename for recording the spatial distribution
  type CountSpatialFileName
     character(len=len_fn),pointer,dimension(:) :: fnx
     character(len=len_fn),pointer,dimension(:) :: fny
     character(len=len_fn),pointer,dimension(:) :: fnz
  end type CountSpatialFileName

  ! Motion type
  type MotionType
     integer :: group_no
     integer :: motion_type
  end type MotionType

  ! Dissociation type
  type DissociationType
     integer,pointer,dimension(:) :: diss_type
  end type DissociationType

  ! Object type
  type ObjectType
     ! read from label file
     integer :: type_no
     character(len=len_wordbuf) :: name
     character(len=len_wordbuf) :: xmol_label
     ! defect configuration
     integer,pointer,dimension(:) :: config
     integer :: total_size
     ! determine the groups that it belongs to
     integer :: n_group_belong
     integer,pointer,dimension(:) :: group_list
     ! control of the motion
     integer :: motion_type
     ! diffusion data
     logical :: does_move
     real(dbl) :: diff_eb
     real(dbl) :: diff_nu
     real(dbl) :: diff_const_rate
     ! dissociation data
     logical :: does_diss
     integer :: diss_type
     real(dbl),pointer,dimension(:) :: diss_eb
     real(dbl),pointer,dimension(:) :: diss_nu
     real(dbl),pointer,dimension(:) :: diss_rd
     real(dbl),pointer,dimension(:) :: diss_const_rate
     integer,pointer,dimension(:) :: n_diss
     type(DissociationType),pointer,dimension(:) :: diss_obj
     ! determine the groups of the reactions that it belongs to
     integer :: n_diss_react_group
     integer,pointer,dimension(:) :: diss_react_group
     ! escape thru free surface
     integer :: n_free_react_group
     integer,pointer,dimension(:) :: free_react_group
  end type ObjectType

  ! Product type
  type ProductType
     integer,pointer,dimension(:) :: prod_type
  end type ProductType

  ! Reaction type
  type ReactionType
     integer :: obj1
     integer :: obj2
     integer :: n_data
     real(dbl),pointer,dimension(:) :: react_eb
     real(dbl),pointer,dimension(:) :: react_nu
     real(dbl),pointer,dimension(:) :: react_rd
     real(dbl),pointer,dimension(:) :: react_rd2
     real(dbl),pointer,dimension(:) :: react_const_rate
     integer,pointer,dimension(:) :: n_new
     type(ProductType),pointer,dimension(:) :: new
     ! determine the groups of the reactions that it belongs to
     integer :: n_react_group
     integer,pointer,dimension(:) :: react_group
  end type ReactionType

  ! Virtually divided simulation box
  type VirtualBox
!     integer :: nx,ny,nz
     integer :: pos(3)
     integer :: n_obj
     integer :: n_neighbor
     integer,pointer,dimension(:) :: neighbor_list
     real(dbl),pointer,dimension(:) :: dx,dy,dz
     integer :: first
  end type VirtualBox

  ! Profile for temperatures
  type TemperatureProfile
     real(dbl) :: temp
     ! 1/2/3
     integer :: loop_condition 
     real(dbl) :: stop_condition
     integer :: external_event_flag
  end type TemperatureProfile

  ! Geometric object
  type GeometricObject
     integer :: index
     integer :: geom_type
     real(dbl) :: xx,yy,zz
     real(dbl) :: x1,x2
     real(dbl) :: y1,y2
     real(dbl) :: z1,z2
     ! dissociation data
     logical :: does_diss
     integer :: diss_type
     real(dbl),pointer,dimension(:) :: diss_eb
     real(dbl),pointer,dimension(:) :: diss_nu
     real(dbl),pointer,dimension(:) :: diss_rd
     real(dbl),pointer,dimension(:) :: diss_const_rate
     integer,pointer,dimension(:) :: diss_n
     type(DissociationType),pointer,dimension(:) :: diss_obj
     ! reaction group
     integer :: n_diss_react_group
     integer,pointer,dimension(:) :: diss_react_group
  end type GeometricObject

  ! Geometric reaction type
  type SinkReactType
     ! gid:index for geometric object
     ! lid:object label
     integer :: gid
     integer :: lid
     ! set reaction data
     integer :: n_data
     real(dbl),pointer,dimension(:) :: react_eb
     real(dbl),pointer,dimension(:) :: react_nu
     real(dbl),pointer,dimension(:) :: react_rd
     real(dbl),pointer,dimension(:) :: react_rd2
     real(dbl),pointer,dimension(:) :: react_const_rate
     integer,pointer,dimension(:) :: n_new
     type(ProductType),pointer,dimension(:) :: new
     ! count for reaction rate
     integer :: n_react_group
     integer,pointer,dimension(:) :: react_group
  end type SinkReactType

  ! Group of reaction rate
  type ReactionRateGroup
     ! type 1 : object+object
     ! type 2 : dissociation
     ! type 3 : sink+object
     ! type 4 : free boundary+object
     integer :: react_type
     integer :: target1,target2
     real(dbl) :: a_count
     real(dbl) :: a_rate
  end type ReactionRateGroup

  ! Object in simulation
  type SimulatedObject
     integer :: index
     integer :: object_type
     ! Position
!     real(dbl) :: px,py,pz
     real(dbl) :: pos(3)
     ! Direction
!     real(dbl) :: dx,dy,dz
     real(dbl) :: vec(3)
     ! d times dist_a0
     real(dbl) :: dr(3)
     ! Virtual Box No.
     integer :: vbox_index
!     integer :: bx,by,bz
     integer :: box(3)
     integer :: next,prev
     ! Event table parameters
     integer :: n_event,n_alloc_event
     ! Is removed from the box?
     logical :: removed
     ! Index for the associated event table
     integer,pointer,dimension(:) :: event_table_list
  end type SimulatedObject

  ! Event table
  type EventTable
     integer :: obj1,obj2
     integer :: obj_seq1,obj_seq2
     integer :: sqnc
     integer :: react_index
     integer :: event_type
     logical :: is_spontaneous
     integer :: profile_table_index
     integer :: profile_table_seq
     integer :: spont_table_index
     logical :: removed
  end type EventTable

  ! Event profile
  type EventProfileTable
     integer :: event_type
     integer :: n_event
     integer :: n_alloc_event
     integer :: external_remain
     integer :: index
     integer :: sqnc
     real(dbl) :: rate_const
     integer,pointer,dimension(:) :: event_list
  end type EventProfileTable

end module derived
